home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** Program: DTS.Lib
- ** File: file.c
- ** Some code from: Traffic Light 2.0 version, by Keith Rollin & John Harvey
- ** Modified by: Eric Soldan
- **
- ** Copyright © 1990-1991 Apple Computer, Inc.
- ** All rights reserved.
- */
-
-
-
- /*****************************************************************************/
-
-
-
- #include "DTS.Lib2.h"
- #include "DTS.Lib.Common.h"
- #include "DTS.Lib.protos.h"
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __FILES__
- #include <Files.h>
- #endif
-
- #ifndef __IMAGECOMPRESSION__
- #include <ImageCompression.h>
- #endif
-
- #ifndef __MOVIES__
- #include <Movies.h>
- #endif
-
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __STRING__
- #include <String.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #include "Utilities.h"
-
-
-
- /*****************************************************************************/
-
-
-
- extern OSType gDocCreator;
- extern short gTypeListLen, gwAppWindow;
- extern long gQTVersion;
- extern SFTypeList gTypeList;
-
- static OSErr Create_OpenFile(FSSpec *file, short *refNum, OSType sftype);
-
-
-
- /*****************************************************************************/
- /*****************************************************************************/
-
-
-
- /* This function does the standard document initialization. */
-
- #pragma segment File
- OSErr DefaultInitDocument(FileRecHndl frHndl, short version, short numUndos, short numSaveUndos)
- {
- TreeObjHndl root, undo;
- OSErr err;
-
- err = noErr;
-
- (*frHndl)->d.doc.fhInfo.version = version;
-
- if (root = NewRootObj(ROOTOBJ, 0)) { /* Create hierarchical data root. */
- (*frHndl)->d.doc.root = root; /* Link file to hierarchical data. */
- undo = NewRootObj(UNDOOBJ, 0); /* Create hierarchical undo root. */
- mDerefRoot(root)->undo = undo; /* Save hierarchical undo root. */
- mDerefRoot(root)->frHndl = frHndl;
- if (undo) {
- (*frHndl)->fileState.defaultDoc = true;
- mDerefUndo(undo)->root = root; /* Point undo back at file root. */
- mDerefUndo(undo)->frHndl = frHndl;
- mDerefUndo(undo)->maxNumUndos = numUndos;
- mDerefUndo(undo)->numSaveUndos = numSaveUndos;
- }
- else {
- DefaultFreeDocument(frHndl);
- err = memFullErr;
- }
- }
- else err = memFullErr;
-
- return(err);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* This function disposes of the document. It checks to see if a file is
- ** currently open for the document. If it is, then the document is closed.
- ** Once there is no open file for the document, the memory occupied by the
- ** document is released. */
-
- #pragma segment File
- OSErr DisposeDocument(FileRecHndl frHndl)
- {
- OSErr err, err2;
- short refNum;
- WindowPtr window;
- Movie movie;
-
- err = noErr;
-
- if (frHndl) {
-
- if ((refNum = (*frHndl)->fileState.refNum) != kInvalRefNum) { /* If file open... */
-
- if ((*frHndl)->fileState.sfType == MovieFileType) /* If movie file... */
- err = CloseMovieFile(refNum); /* Close it. */
-
- else /* If not movie file... */
- err = FSClose(refNum); /* Close it. */
- }
-
- CloseDocResFile(frHndl); /* Close resource fork, if opened. */
-
- window = (*frHndl)->fileState.window;
- err2 = DoFreeDocument(frHndl); /* Free all application-specific document ram. */
-
- if (movie = (*frHndl)->fileState.movie)
- DisposeMovie(movie); /* If we have a movie, dispose it. */
-
- if (window)
- SetWRefCon(window, (long)nil); /* Mark window as no longer having a document. */
-
- if (!err)
- err = err2;
-
- DisposeHandle((Handle)frHndl); /* Release memory for the document handle. */
- }
-
- return(err);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* This function creates a new document. A handle is created as the
- ** reference to the document. Header information is placed in this handle.
- ** The application-specific data follows this header information. The
- ** handle is returned (or nil upon failure), and typically the handle is
- ** then stored in the refCon field of the window. Note that this is a
- ** convention, and is not mandatory. This allows a document to exist that
- ** has no window. A document with no window is useful when the application
- ** is called from the finder in response to a print request. The document
- ** can be loaded and printed without involving a window on the screen. */
-
- #pragma segment File
- OSErr NewDocument(FileRecHndl *returnHndl, OSType sftype, Boolean incTitleNum)
- {
- long size;
- FileRecHndl frHndl;
- FileRecPtr frPtr;
- Str255 untitled;
- StringPtr pstr;
- OSErr err;
- short i;
- Movie movie;
- static short untitledCount;
-
- err = memFullErr; /* Assume that we will fail. */
-
- size = InitDocumentSize(sftype);
- /* Call the application and ask it how big the frHndl should be for
- ** this document type. We can't know, so we'll ask. */
-
- if (frHndl = (FileRecHndl)NewHandleClear(size)) {
- /* Create (or try to) the frHndl, initialized to all 0's */
-
- if (returnHndl)
- *returnHndl = frHndl;
-
- for (i = gTypeListLen; --i;) if (sftype == gTypeList[i]) break;
- /* Walk the typeList to find this file type. We are interested in
- ** where we find the entry. The position we find it is used as a
- ** string number into the rDefaultTitles STR# resource. We get
- ** an individual string from this location. This allows us to
- ** have different default titles for different document types. */
-
- for (++i; i; i--) {
- GetIndString(untitled, rDefaultTitles, i);
- if (untitled[0]) break; /* Quit if we succeeded at getting one. */
- }
-
- (*frHndl)->fileState.modNum = GetModNum();
- /* In case GetModNum gets moved to another code segment, set this value
- ** prior to dereferencing frHndl into frPtr. */
-
- frPtr = *frHndl;
- frPtr->fileState.sfType = sftype;
- frPtr->fileState.modTick = TickCount();
- frPtr->fileState.refNum = kInvalRefNum;
- frPtr->fileState.resRefNum = kInvalRefNum;
- frPtr->fileState.fss.vRefNum = kInvalVRefNum;
- frPtr->fileState.windowID = rWindow;
- /* The above sets the fileState constants for the document. Note
- ** that we use a default 'WIND' ID for the expected window resource.
- ** This can be changed later, if the default isn't good enough. */
-
- frPtr->fileState.getDocWindow = GetStaggeredWindow;
- frPtr->fileState.calcFrameRgnProc = CalcFrameRgn;
- frPtr->fileState.contentClickProc = ContentClick;
- frPtr->fileState.contentKeyProc = ContentKey;
- frPtr->fileState.drawFrameProc = DrawFrame;
- frPtr->fileState.freeDocumentProc = FreeDocument;
- frPtr->fileState.freeWindowProc = FreeWindow;
- frPtr->fileState.imageProc = ImageDocument;
- frPtr->fileState.initContentProc = InitContent;
- frPtr->fileState.readDocumentProc = ReadDocument;
- frPtr->fileState.readDocumentHeaderProc = DefaultReadDocumentHeader;
- frPtr->fileState.resizeContentProc = ResizeContent;
- frPtr->fileState.scrollFrameProc = ScrollFrame;
- frPtr->fileState.undoFixupProc = UndoFixup;
- frPtr->fileState.windowCursorProc = WindowCursor;
- frPtr->fileState.writeDocumentProc = WriteDocument;
- frPtr->fileState.writeDocumentHeaderProc = DefaultWriteDocumentHeader;
- /* Initialize all of the procedure pointers to default values.
- ** If the defaults aren't any good, they will be changed later. */
-
- frPtr->fileState.attributes = gwAppWindow;
- /* Set window attributes for the main document type. If the document
- ** is not the main type, then the application's InitDocument function
- ** will have to change it. */
-
- pstr = frPtr->fileState.fss.name;
- pcpy(pstr, untitled);
- if (incTitleNum)
- ++untitledCount;
- pcatdec(pstr, untitledCount);
- /* Create the default document title. It is stored in the FSSpec,
- ** as we can't place it in the window title. We don't have a window
- ** yet to "title". This will happen later. The title is gotten from
- ** the FSSpec, so we are effectively done. */
-
- err = InitDocument(frHndl);
- /* Call the application for any additional document initialization.
- ** Other handles may need to be allocated. The default values above
- ** may be incorrect for a certain document type. This gives the
- ** application a chance to change any defaults that are incorrect. */
-
- if ((*frHndl)->fileState.sfType == MovieFileType) {
- movie = NewMovie(newMovieActive);
- err = GetMoviesError();
- if (!err) {
- ClearMovieChanged(movie);
- (*frHndl)->fileState.movie = movie;
- }
- }
-
- if (err) {
- DisposeHandle((Handle)frHndl);
- if (returnHndl)
- *returnHndl = nil;
- /* If the application couldn't complete the document
- ** initialization, pitch the handle. */
- }
- }
-
- return(err);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment File
- OSErr OpenDocument(FileRecHndl *result, FSSpecPtr fileToOpen, char permission)
- {
- StandardFileReply reply;
- short refNum;
- FileRecHndl frHndl;
- OSErr err;
- FSSpec myFileSpec;
- DialogPtr openDialog;
- short item;
- FInfo finderInfo;
- Boolean openMovie;
- Movie movie;
- static SFTypeList typeList = {MovieFileType};
-
- *result = nil; /* Assume we will fail. */
-
- openMovie = false;
- if (fileToOpen == kOpenMovie) {
- if (!gQTVersion) return(paramErr); /* Can't do movies without QuickTime. */
- fileToOpen = nil;
- openMovie = true;
- }
-
- if (!fileToOpen) {
- if (openMovie) {
- StandardGetFilePreview(0L, 1, typeList, &reply);
- if (reply.sfGood)
- myFileSpec = reply.sfFile;
- else
- return(userCanceledErr); /* User canceled. */
- }
- else {
- if (DisplayGetFile(&reply, gTypeListLen, gTypeList)) /* Let user pick file. */
- myFileSpec = reply.sfFile; /* User's choice. */
- else
- return(userCanceledErr); /* User canceled. */
- }
- }
- else {
- err = HGetFInfo(fileToOpen->vRefNum, fileToOpen->parID, fileToOpen->name, &finderInfo);
- if (err) return(err);
- reply.sfType = finderInfo.fdType; /* OSType of file. */
- myFileSpec = *fileToOpen; /* Pre-designated file to open. */
- }
-
- err = NewDocument(&frHndl, reply.sfType, false);
- if (err) return(err);
- /* We couldn't create an empty document, so give it up. */
-
- err = HOpenDF(myFileSpec.vRefNum, myFileSpec.parID, myFileSpec.name, permission, &refNum);
- if (err == paramErr)
- err = HOpen(myFileSpec.vRefNum, myFileSpec.parID, myFileSpec.name, permission, &refNum);
-
- if (err == opWrErr) {
-
- ParamText(myFileSpec.name, nil, nil, nil);
- openDialog = GetCenteredDialog(rOpenReadOnly, nil, nil, (WindowPtr)-1L);
- if (!openDialog) {
- DisposeDocument(frHndl);
- return(err);
- }
-
- OutlineDialogItem(openDialog, kOpenYes);
- DoSetCursor(&qd.arrow);
- UnhiliteWindows();
- ModalDialog((ModalFilterProcPtr)KeyEquivFilter, &item);
- DisposeDialog(openDialog);
- HiliteWindows();
- if (item != kOpenYes) {
- DisposeDocument(frHndl);
- return(userCanceledErr);
- }
-
- (*frHndl)->fileState.readOnly = true;
- permission = fsRdPerm;
- err = HOpenDF(myFileSpec.vRefNum, myFileSpec.parID, myFileSpec.name, permission, &refNum);
- if (err == paramErr)
- err = HOpen(myFileSpec.vRefNum, myFileSpec.parID, myFileSpec.name, permission, &refNum);
- }
-
- if (err) {
- DisposeDocument(frHndl);
- return(err);
- }
-
- if ((*frHndl)->fileState.sfType == MovieFileType) {
- FSClose(refNum); /* Close file, as it wasn't opened as movie. */
- if (movie = (*frHndl)->fileState.movie) {
- DisposeMovie(movie); /* NewDocument created an empty movie, */
- (*frHndl)->fileState.movie = nil; /* so first get rid of it. */
- }
- err = OpenMovieFile(&myFileSpec, &refNum, permission);
- if (err) {
- DisposeDocument(frHndl);
- return(err);
- }
- }
-
- (*frHndl)->fileState.fss = myFileSpec;
- (*frHndl)->fileState.refNum = refNum;
-
- if (err = DoReadDocument(frHndl)) {
- DisposeDocument(frHndl);
- return(err);
- }
-
- *result = frHndl;
- return(noErr);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment File
- OSErr SaveDocument(FileRecHndl frHndl, WindowPtr window, short saveMode)
- {
- Str255 closeOrQuit;
- short item, refNum, resID;
- long createFlags;
- StandardFileReply reply;
- OSErr err;
- Movie movie;
- Boolean doPrompt;
- DialogPtr saveDialog;
-
- /* When entering, saveMode is set to the menu command number of the
- ** the item that prompted this. Current settings are kSave, kSaveAs,
- ** kClose, and kQuit. */
-
- if (saveMode != kSaveAs) { /* If not save as... */
- if (!(*frHndl)->fileState.docDirty) { /* If file clean... */
- if (!(*frHndl)->fileState.readOnly)
- DoWriteDocumentHeader(frHndl);
- /* Write out document location and print record information. */
- return(noErr); /* Consider it saved. */
- }
- }
-
- pcpy(reply.sfFile.name, (*frHndl)->fileState.fss.name);
-
- if ((saveMode == kClose) || (saveMode == kQuit)) {
- /* If implicit save... */
-
- GetIndString(closeOrQuit, rFileIOStrings,
- (saveMode == kClose) ? sWClosing : sQuitting);
- ParamText(reply.sfFile.name, closeOrQuit, nil, nil);
-
- saveDialog = GetCenteredDialog(rYesNoCancel, nil, window, (WindowPtr)-1L);
-
- if (saveDialog) {
- OutlineDialogItem(saveDialog, kSaveYes);
- DoSetCursor(&qd.arrow);
- UnhiliteWindows();
- ModalDialog((ModalFilterProcPtr)KeyEquivFilter, &item);
- DisposeDialog(saveDialog);
- HiliteWindows();
- }
- else
- item = kSaveNo;
- /* If the dialog isn't displayed, then AppleScript doesn't want it to.
- ** In this case, we were probably AppleScripted the whole time, so
- ** the document is an AppleScript-produced document. The script is
- ** done with the document, so ditch the document. */
-
- if (item != kSaveYes) {
- err = noErr;
- if (item == kSaveCanceled)
- err = userCanceledErr;
- return(err);
- }
- }
-
- doPrompt = (
- (saveMode == kSaveAs) ||
- ((*frHndl)->fileState.refNum == kInvalRefNum)
- );
-
- if (doPrompt) {
- /* Prompt with SFGetFile if doing a Save As or have never saved before. */
-
- if (!DisplayPutFile(&reply)) return(userCanceledErr); /* User canceled the save. */
-
- if ((*frHndl)->fileState.sfType != MovieFileType) {
- if ((*frHndl)->fileState.refNum != kInvalRefNum) {
- if ((*frHndl)->fileState.sfType != MovieFileType) {
- CloseDocResFile(frHndl); /* Close resource fork, if opened. */
- FSClose((*frHndl)->fileState.refNum);
- }
- } /* Close the old file. Don't respond to any error here because
- ** the user may be trying to do a save-as because their old file
- ** is bad. If we fail to close the old file, and then respond
- ** to the error, the user won't get the opportunity to save
- ** their document to a new file. */
-
- (*frHndl)->fileState.refNum = kInvalRefNum;
- (*frHndl)->fileState.fss.vRefNum = kInvalVRefNum;
- if (err = Create_OpenFile(&reply.sfFile, &refNum, (*frHndl)->fileState.sfType))
- return(err);
- }
- else {
- createFlags = createMovieFileDeleteCurFile;
- err = CreateMovieFile(&reply.sfFile, gDocCreator, 0, createFlags, &refNum, nil);
- if (err) return(err);
- resID = 0;
- err = AddMovieResource((*frHndl)->fileState.movie, refNum, &resID, nil);
- if (err) return(err);
- (*frHndl)->fileState.movieResID = resID;
- }
-
- (*frHndl)->fileState.fss = reply.sfFile; /* This is the new file. */
- (*frHndl)->fileState.refNum = refNum;
-
- if (window)
- NewWindowTitle(window, nil);
- }
- else {
- if ((*frHndl)->fileState.sfType == MovieFileType) {
- movie = (*frHndl)->fileState.movie;
- refNum = (*frHndl)->fileState.refNum;
- resID = (*frHndl)->fileState.movieResID;
- err = UpdateMovieResource(movie, refNum, resID, nil);
- if (err) return(err);
- }
- }
-
- if (err = DoWriteDocument(frHndl)) return(err);
-
- (*frHndl)->fileState.docDirty = false;
- (*frHndl)->fileState.readOnly = false;
- return(noErr);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* ConvertOldToNewSFReply
- **
- ** struct StandardFileReply { struct SFReply {
- ** Boolean sfGood; <- Boolean good;
- ** Boolean sfReplacing; <- Boolean copy;
- ** OSType sfType; <- OSType fType;
- ** FSSpec sfFile;
- ** vRefNum; <- real vRefnum from (short vRefNum)
- ** parID; <- real dirID from (short vRefNum)
- ** name; <- Str63 fName;
- ** ScriptCode sfScript; <- iuSystemScript
- ** short sfFlags; <- 0
- ** Boolean sfIsFolder; <- false
- ** Boolean sfIsVolume; <- false
- ** long sfReserved1; <- 0
- ** short sfReserved2; <- 0
- ** }; };
- */
-
- #pragma segment File
- void ConvertOldToNewSFReply(SFReply *oldReply, StandardFileReply *newReply)
- {
- OSErr err;
- long ignoredProcID;
-
- newReply->sfGood = oldReply->good;
- newReply->sfReplacing = oldReply->copy; /* Correct assignment? */
- newReply->sfType = oldReply->fType;
-
- err = GetWDInfo(oldReply->vRefNum,
- &newReply->sfFile.vRefNum,
- &newReply->sfFile.parID,
- &ignoredProcID);
- pcpy(newReply->sfFile.name, oldReply->fName);
-
- /* Punt on the rest... */
- newReply->sfScript = iuSystemScript;
- newReply->sfFlags = 0;
- newReply->sfIsFolder = false;
- newReply->sfIsVolume = false;
- newReply->sfReserved1 = 0;
- newReply->sfReserved2 = 0;
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* Opens the file specified by the passed FSSpec, creating it if it doesn't
- ** already exist. Returns the refnum of the open file to the application.
- ** File Manager errors are reported and returned. */
-
- #pragma segment File
- OSErr Create_OpenFile(FSSpec *file, short *refNum, OSType sftype)
- {
- OSErr err;
-
- err = HCreate(file->vRefNum, file->parID, file->name, gDocCreator, sftype);
- if (err == dupFNErr) {
-
- /* The user already told Standard File to replace the old file
- so let's get rid of it. */
-
- HDelete(file->vRefNum, file->parID, file->name);
-
- /* Try creating it again. */
- err = HCreate(file->vRefNum, file->parID, file->name, gDocCreator, sftype);
- }
-
- if (!err) {
- err = HOpenDF(file->vRefNum, file->parID, file->name, fsRdWrPerm, refNum);
- if (err == paramErr)
- err = HOpen(file->vRefNum, file->parID, file->name, fsRdWrPerm, refNum);
- if (err)
- HDelete(file->vRefNum, file->parID, file->name);
- }
-
- return(err);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* Simple routine to display a list of files with our file type. */
-
- #pragma segment File
- Boolean DisplayGetFile(StandardFileReply *reply, short typeListLen, SFTypeList typeList)
- {
- Point where = {100, 100};
- SFReply oldReply;
-
- if (gSystemVersion >= 0x0700) /* If new standard file available... */
- StandardGetFile(nil, typeListLen, typeList, reply);
-
- else {
- SFGetFile(where, "\pSelect a document to open.",
- nil, typeListLen, typeList, nil, &oldReply);
- ConvertOldToNewSFReply(&oldReply, reply);
- }
-
- return(reply->sfGood);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* Displays the StandardFile PutFile dialog box. Fills out the passed reply
- ** record, and returns the sfGood field as a result. */
-
- #pragma segment File
- Boolean DisplayPutFile(StandardFileReply *reply)
- {
- Str255 prompt;
- Point where = {100, 100};
- SFReply oldReply;
-
- GetIndString(prompt, rFileIOStrings, sSFprompt);
-
- if (gSystemVersion >= 0x0700) /* If new standard file available... */
- StandardPutFile(prompt, reply->sfFile.name, reply);
- else {
- SFPutFile(where, prompt, reply->sfFile.name, nil, &oldReply);
- ConvertOldToNewSFReply(&oldReply, reply);
- }
-
- return(reply->sfGood);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* Use the resource fork for the designated document file. This function
- ** also returns the old CurResFile, so you can set it back when you are done.
- ** Simply call this function, whether or not you have a resource fork. If
- ** there isn't a resource fork, then one will be created. If there is one,
- ** but it isn't open yet, it will be opened. If it is already opened, it
- ** sets it as the current resource fork. What more do you want? */
-
- #define fcbFlgRBit 0x200
-
- #pragma segment File
- OSErr UseDocResFile(FileRecHndl frHndl, short *oldRes, char perm)
- {
- OSErr err;
- FSSpec fss;
- short res, vrn;
- long pid;
- FCBPBRec pb;
-
- if (oldRes)
- *oldRes = CurResFile();
-
- if ((res = (*frHndl)->fileState.resRefNum) != kInvalRefNum) {
- UseResFile(res); /* If the resource fork already open, use it. */
- return(ResError());
- }
-
- memset(&pb, 0, sizeof(FCBPBRec)); /* Make most of the param block happy. */
- pb.ioRefNum = res = (*frHndl)->fileState.refNum;
- if (err = PBGetFCBInfoSync(&pb)) return(err);
- if (pb.ioFCBFlags & fcbFlgRBit) {
- (*frHndl)->fileState.resRefNum = res;
- UseResFile(res);
- return(ResError());
- }
-
- fss = (*frHndl)->fileState.fss;
- vrn = fss.vRefNum;
- pid = fss.parID;
-
- res = HOpenResFile(vrn, pid, fss.name, perm);
- /* Try opening the resource fork. */
-
- if (err = ResError()) {
- if (err != eofErr) return(err); /* Some errors we can't handle here. */
- HCreateResFile(vrn, pid, fss.name); /* No resource fork, so create one. */
- if (err = ResError()) return(err); /* Error creating the resource fork. */
- res = HOpenResFile(vrn, pid, fss.name, perm); /* Now that it exists, open it. */
- err = ResError(); /* Return whatever error occurs. */
- }
-
- if (!err) { /* If no error, then we can use the resource fork. */
- (*frHndl)->fileState.resRefNum = res;
- UseResFile(res);
- err = ResError();
- }
-
- return(err);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* If there is a resource fork open for this document, this closes it. */
-
- #pragma segment File
- OSErr CloseDocResFile(FileRecHndl frHndl)
- {
- short res;
-
- if ((res = (*frHndl)->fileState.resRefNum) == kInvalRefNum) return(noErr);
- /* If it was never opened, then there's nothing to close. */
-
- if ((*frHndl)->fileState.refNum == res) {
- (*frHndl)->fileState.resRefNum = kInvalRefNum;
- return(noErr);
- }
-
- CloseResFile(res); /* Close the resource fork. */
- (*frHndl)->fileState.resRefNum = kInvalRefNum; /* Mark it as closed. */
-
- return(ResError());
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment File
- long GetModNum(void)
- {
- static modNum = 0;
-
- return(++modNum);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* This function returns the state of the document. If the document
- ** is dirty, then true is returned. If the document is clean, then false
- ** is returned. */
-
- #pragma segment File
- Boolean GetDocDirty(FileRecHndl frHndl)
- {
- if (frHndl) return((*frHndl)->fileState.docDirty);
- return(false);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* This function returns the state of the window's document. If the document
- ** is dirty, then true is returned. If the document is clean, or the window
- ** has no document, then false is returned. */
-
- #pragma segment File
- Boolean GetWindowDirty(WindowPtr window)
- {
- if (IsAppWindow(window)) return(GetDocDirty((FileRecHndl)GetWRefCon(window)));
- return(false);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment File
- void SetDocDirty(FileRecHndl frHndl)
- {
- if (frHndl) {
- (*frHndl)->fileState.docDirty = true;
- (*frHndl)->fileState.modNum = GetModNum();
- (*frHndl)->fileState.modTick = TickCount();
- }
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment File
- void SetWindowDirty(WindowPtr window)
- {
- if (IsAppWindow(window))
- SetDocDirty((FileRecHndl)GetWRefCon(window));
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment File
- /* The SetDefault function sets the default volume and directory to the volume specified
- ** by newVRefNum and the directory specified by newDirID. The current default volume
- ** and directory are returned in oldVRefNum and oldDir and should be used to restore
- ** things to their previous condition *as soon as possible* with the RestoreDefault
- ** function. These two functions are designed to be used as a wrapper around
- ** Standard C I/O routines where the location of the file is implied to be the
- ** default volume and directory. In other words, this is how you should use these
- ** functions:
- **
- ** err = SetDefault(newVRefNum, newDirID, &oldVRefNum, &oldDirID);
- ** if (!err)
- ** {
- ** // call the Stdio functions like remove, rename, tmpfile, fopen,
- ** // freopen, etc. or non-ANSI extentions like fdopen, fsetfileinfo,
- ** // create, open, unlink, etc. here!
- **
- ** err = RestoreDefault(oldVRefNum, oldDirID);
- ** }
- **
- ** By using these functions as a wrapper, you won't need to open a working directory
- ** (because they use HSetVol) and you won't have to worry about the effects of using
- ** HSetVol (documented in Technical Note #140: Why PBHSetVol is Dangerous
- ** and in the Inside Macintosh: Files book in the description of the HSetVol and
- ** PBHSetVol functions) because the default volume/directory is restored before
- ** giving up control to code that might be affected by HSetVol.
- ** Use this and the below call instead of the old-style FSpSetWD and FSpResetWD. */
-
- OSErr SetDefault(short newVRefNum, long newDirID, short *oldVRefNum, long *oldDirID)
- {
- OSErr err;
-
- err = HGetVol(nil, oldVRefNum, oldDirID);
- /* Get the current default volume/directory. */
-
- if (!err)
- err = HSetVol(nil, newVRefNum, newDirID);
- /* Set the new default volume/directory */
-
- return(err);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment File
- OSErr RestoreDefault(short oldVRefNum, long oldDirID)
- {
- OSErr err;
- short defaultVRefNum;
- long defaultDirID;
- long defaultProcID;
-
- err = GetWDInfo(oldVRefNum, &defaultVRefNum, &defaultDirID, &defaultProcID);
- /* Determine if the default volume was a wdRefNum. */
-
- if (!err) {
- /* Restore the old default volume/directory, one way or the other. */
-
- if (defaultDirID != fsRtDirID)
- err = SetVol(nil, oldVRefNum);
- /* oldVRefNum was a wdRefNum - use SetVol */
- else
- err = HSetVol(nil, oldVRefNum, oldDirID);
- /* oldVRefNum was a real vRefNum - use HSetVol */
- }
-
- return(err);
- }
-
-
-
-